﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;

namespace Abide_Halo_Library.Halo_2_Map
{
    public partial class StringIDBrowser : Form
    {
        private delegate void SetItems(StringID[] ids);

        public string SelectedString
        {
            get { return selectedString.ID; }
            set { SelectString(value); }
        }
        public short SelectedIndex
        {
            get { return selectedString.Index; }
            set { SelectIndex(value); }
        }

        private StringID selectedString = StringID.Empty;
        private readonly StringID[] strings;

        public StringIDBrowser(string[] strings)
        {
            //Setup
            this.strings = new StringID[strings.Length];
            for (short i = 0; i < strings.Length; i++)
                this.strings[i] = new StringID(strings[i], i);

            //Initialize
            InitializeComponent();
        }

        private void StringIDBrowser_Load(object sender, EventArgs e)
        {
            //Set
            SetStringIDs(strings);
        }

        private void filterBox_TextChanged(object sender, EventArgs e)
        {
            //Update
            ThreadPool.QueueUserWorkItem(w => { Filter(filterBox.Text); });
        }

        private void stringList_SelectedIndexChanged(object sender, EventArgs e)
        {
            //Check
            if (selectedString.Index >= 0)
            {
                //Set
                selectedString = strings[selectedString.Index];
                OKButton.Enabled = true;
            }
        }

        private void SetStringIDs(StringID[] stringIDs)
        {
            if (InvokeRequired)
                Invoke(new SetItems(SetStringIDs), stringIDs);
            else
            {
                //Clear
                stringList.Items.Clear();
                foreach (StringID id in stringIDs)
                    stringList.Items.Add(id);

                //Set
                stringList.SelectedItem = selectedString;
            }
        }

        private void SelectString(string value)
        {
            //Find...
            StringID id = StringID.Empty;
            foreach (StringID stringId in strings)
                if (id.ID == value)
                { id = stringId; break; }

            //Set
            this.selectedString = id;
        }

        private void SelectIndex(int index)
        {
            //Set
            this.selectedString = strings[index];
        }

        private void Filter(string filter)
        {
            //Iterate through each.
            List<StringID> Matches = new List<StringID>();
            foreach (StringID id in strings)
            {
                if (Regex.IsMatch(id.ID, filter))
                    Matches.Add(id);
            }

            //Set Items
            SetStringIDs(Matches.ToArray());
        }

        public struct StringID
        {
            public string ID
            {
                get { return id; }
            }
            public short Index
            {
                get { return index; }
            }
            public short Length
            {
                get { return length; }
            }

            public static readonly StringID Empty = new StringID() { id = string.Empty, length = 0, index = 0 };

            private string id;
            private short index;
            private short length;

            public StringID(string sid, short index)
            {
                this.id = sid;
                this.index = index;
                this.length = Convert.ToInt16(sid.Length);
            }
            public StringID(string sid, int index)
            {
                this.id = sid;
                this.index = Convert.ToInt16(index);
                this.length = Convert.ToInt16(sid.Length);
            }

            public int GetID()
            {
                int index = this.index;
                int length = this.length << 8;
                return index | length;
            }
            public override string ToString()
            {
                return string.Format("{0}: {1}", index, id);
            }
        }
    }
}
